package serviceset4;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.web.client.RestTemplate;
import serviceset4.feign.ServiceSet3Hystrix;
import serviceset4.restTemplate.ServiceSet3Proxy;

@ComponentScan
@EnableHystrix
@EnableOAuth2Client
@EnableFeignClients
@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
@EnableAutoConfiguration
public class Application {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public ServiceSet3Hystrix serviceSet3Hystrix() {
        return new ServiceSet3Hystrix();
    }

    @Bean
    public ServiceSet3Proxy serviceSet3Proxy() {
        return new ServiceSet3Proxy();
    }

    @Configuration
    @EnableResourceServer
    protected class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        private static final String RESOURCE_ID = "SERVICE-SET-2";
        private static final String SECURED_READ_SCOPE = "#oauth2.hasScope('read')";
        private static final String SECURED_WRITE_SCOPE = "#oauth2.hasScope('write')";
        private static final String SECURED_PATTERN = "/sampleApi2/**";

        @Autowired
        private ResourceServerProperties sso;

        @Bean
        @Primary
        public ResourceServerTokenServices tokenServices() {
            return new UserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
        }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .requestMatchers().antMatchers(SECURED_PATTERN)
                    .and()
                    .authorizeRequests()
                        .anyRequest().authenticated();
//                        .antMatchers(HttpMethod.POST, SECURED_PATTERN).access(SECURED_WRITE_SCOPE)
//                        .anyRequest().access(SECURED_READ_SCOPE);
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
